package com.arcaneshift.servlet.util.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.arcaneshift.model.abstracts.AbstractCard;
import com.arcaneshift.model.action.game.CreatureCard;
import com.arcaneshift.model.action.game.SpellCard;
import com.arcaneshift.model.request.AddDeckRequest;
import com.arcaneshift.model.response.AddDeckResponse;
import com.arcaneshift.model.util.CardType;
import com.arcaneshift.security.exceptions.CardException;
import com.arcaneshift.servlet.abstracts.XMLParserBase;
import com.arcaneshift.servlet.util.network.HTTPProtocol;
import com.common.model.abstracts.AbstractRequest;
import com.common.model.abstracts.AbstractResponse;
import com.common.security.exceptions.HTTPException;
import com.common.security.exceptions.ParserException;

public class AddDeckXMLParser extends XMLParserBase {

	/**
	 * @throws HTTPException
	 * @throws ParserException
	 * @throws ParserException.CONVERSION_EXCEPTION
	 * @throws CardException.CARD_TYPE_NOT_SUPPORTED
	 */
	@Override
	public AbstractRequest parseRequest(InputStream stream) throws HTTPException, ParserException {
		AddDeckRequest request = new AddDeckRequest();
		
		Document document = createDocument(stream);
		
		Node actionNode = getActionNode(document);
		Node contentNode = getContentNode(document);
		
		insertAction(actionNode, request);
		Element element = getContent(contentNode);
		
		Element session = getElement(element, HTTPProtocol.SESSION);
		Element deck = getElement(element, HTTPProtocol.DECK);
		Element user = getElement(element, HTTPProtocol.USER, true);
		List<Element> cards = getAllElements(deck, HTTPProtocol.CARD);
		
		request.setSessionId(session.getAttribute(HTTPProtocol.ATTRIBUTE_VALUE));
		request.setName(deck.getAttribute(HTTPProtocol.ATTRIBUTE_VALUE));
		
		if (user != null) {
			try {
				Long userId = Long.parseLong(user.getAttribute(HTTPProtocol.ATTRIBUTE_VALUE));
				request.setUserId(userId);
			} catch (NumberFormatException exception) {
				throw new ParserException(ParserException.CONVERSION_EXCEPTION);
			}
		}
		
		AbstractCard abstractCard = null;
		List<AbstractCard> abstractCards = new ArrayList<AbstractCard>();
		
		for (Element card : cards) {
			if (CardType.CREATURE.equals(card.getAttribute(HTTPProtocol.ATTRIBUTE_TYPE))) {
				abstractCard = new CreatureCard();
			} else if (CardType.SPELL.equals(card.getAttribute(HTTPProtocol.ATTRIBUTE_TYPE))) {
				abstractCard = new SpellCard();
			} else {
				throw new CardException(CardException.CARD_TYPE_NOT_SUPPORTED);
			}
			abstractCard.setName(card.getAttribute(HTTPProtocol.ATTRIBUTE_VALUE));
			abstractCards.add(abstractCard);
		}
		request.setCards(abstractCards);
		
		return request;
	}

	@Override
	public String parseResponse(AbstractResponse abstractResponse) throws ParserException {
		AddDeckResponse response = null;
		if (abstractResponse instanceof AddDeckResponse) {
			response = (AddDeckResponse) abstractResponse;
		} else {
			throw new ParserException(ParserException.RESPONSE_MATCH_ERROR);
		}
		
		StringBuilder builder = new StringBuilder();
		
		builder.append(HTTPProtocol.RESPONSE_TAG);
		builder.append(HTTPProtocol.CLOSE_TAG);
		builder.append(HTTPProtocol.END_LINE);
		builder.append(getAction(response.getRequestAction()));
		builder.append(HTTPProtocol.CONTENT_TAG);
		builder.append(HTTPProtocol.END_LINE);
		builder.append(HTTPProtocol.CONTENT_END_TAG);
		builder.append(HTTPProtocol.END_LINE);
		builder.append(HTTPProtocol.RESPONSE_END_TAG);
		
		return builder.toString();
	}

}
